home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-10-22 | 14.6 KB | 280 lines | [TEXT/RLAB] |
- FUNCTION:
-
- This help file covers several aspects of functions:
-
- 1) Introduction
-
- 2) Variable scoping
-
- 3) Function arguments
-
- 4) Function return values
-
- 5) Function recursion
-
- 6) Special topics
-
- 1) Introduction ------------------------------------------------
-
- Functions are an essential part of the language. Learning how
- to create and use functions will greatly add to the benefits
- of using RLaB.
-
- It is important to remember that functions adhere to the RLaB
- rule: "everything is a variable". Functions are variables, and
- like the other types or classes of variables in RLaB can be
- printed (although it will be hard to understand the output),
- copied, and renamed. Functions cannot act as operands to
- numeric operators, although the result of the function usually
- can. Since function calls are evaluated "in-place" they can be
- used within other expressions, for example:
-
- > sin(cos(1.0))
- 0.514
-
- > sin( [ cos(0.3), sqrt(cos(0.3)) ] )
- 0.817 0.829
-
-
- The syntax used for function definition is a little unusual...
-
- Example:
-
- > sum = function (s)
- {
- local(i, Sum);
- Sum = 0;
- for(i in 1:size(s)) {
- Sum = Sum + s[i];
- }
- return Sum;
- };
- >
-
- creates a function, and assigns it to the variable `sum'.
- Sum is invoked like:
-
- > sum( [1,2,3,4,5] )
- 15
-
- 2) Variable Scopes ---------------------------------------------
-
- When you start a RLaB session, either interactively or in
- batch-mode, you create an environment. The environment or
- workspace consists of the built-in functions, and any other
- variables or functions you may have added. The workspace will
- also be referred to as the global-symbol-table or the global
- scope.
-
- There are two other types of environment available: a
- function's local environment and a file's static environment
- (we will use the term environment and scope interchangeably).
-
- A function's local scope is temporary, it is created when the
- function is invoked, and is destroyed when the function
- returns. A file's static scope is created when the file is
- loaded, and remains intact until the RLaB session is
- terminated.
-
- The different scopes serve to protect data from operations
- that occur in the other scopes. There is some degree of
- overlap in order to allow flexibility. Functions can affect
- file-static and global scopes; statements within files can
- affect statements within other files and the global
- scope. More simply put, the "lower" scopes generally have
- access to the "higher" scopes. When a variable is used, RLaB
- uses certain rules to "bind" the variable. When we use the
- term bind or bound, we mean that the variable name is
- associated with an entry in one of the three types of symbol
- tables.
-
- File-Scope: Variables that are in a file (but not within a
- function) are bound to the global-symbol-table
- (global-scope or global-environment) unless a
- static declaration is used. When a variable is
- declared static (see `help static') it is bound to
- the file's symbol table. From that point on, the
- variable will remain bound to the file's
- scope. When a variable is declared static, it is
- not visible from the global environment or from
- any other files.
-
- Function Local Scope: In general, variables used within a
- function (other than the function's arguments) are
- bound to the function's local scope (there are
- ways to override this behavior). Variables bound
- to a function's local scope are not visible from a
- file's scope or from the global scope. They are
- created (undefined) when the function is invoked,
- and destroyed when the function returns.
-
- There are exceptions: variables used in a function
- context are bound to the global-symbol-table. For
- example:
-
- x = a * sin ( pi )
-
- `sin' is used in a function context, and is bound
- to the global scope, while `x', `a', and`pi' are
- bound to the function's local environment.
-
- Function's that are defined within a file have
- full access to the file's static variables.
- Function variables will be bound to the file's
- scope before local binding occurs. For example:
-
- ---- beginning of file.r ----
-
- static (A, pi)
- A = 1.e-3;
- pi = atan(1)*4;
-
- fun = function ( a ) { return A*sin(pi*A*a); }
-
- ---- end of file.r ----
-
- When `fun' is created it binds `A' and `pi'
- to file.r's static environment.
-
- There are two declarations: `global' and `local'
- that can be used to override the default behavior
- if necessary. Variables declared local will be
- bound to to the function's local scope, and
- variable declared global will be bound to the
- global scope.
-
- **NOTE: There is one more special exception (for
- advanced usage): Function variables can be
- members of a list, or members of a list, that is a
- member of another list, etc, etc... In effect this
- allows users to hide or protect variables and
- functions in an arbitrary manner. Thus, when RLaB
- sees something like:
-
- ML.e1.signal( a )
-
- it does not bind `ML' to the global scope. In this
- context RLaB cannot bind the function until
- runtime, so the list is by default bound to the
- function's local scope. This behavior can be
- changed by using the global, or static
- declarations.
-
-
- The built-in function fvscope performs a variable scope
- analysis of any user-function. For example:
-
- ---- beginning of file.r ----
- static (stat) // Keep track of some statistic.
- stat.n = 0;
- stat.total = 0;
-
- x = function (a, b)
- {
- local (a)
- global (pi)
-
- for( i in 1:a.nr )
- {
- a[;i] = a[;i]*norm(a);
- }
- retv = 2*pi*norm(a)*b;
- stat.n = stat.n + 1;
- stat.total = stat.total + retv;
-
- return << val = retv; avg = stat.total/stat.n >>;
- };
- ---- end of file.r ----
-
- > local ("./file.r");
- > fvscope(x);
- Function Variable SCOPE analysis for : x
- Filename: ./jnk.r
-
- line GLOBAL ARG LOCAL
-
- 10 Local-Var: i
- 10 Local-Var: a
- 12 Local-Var: a
- 12 Local-Var: i
- 12 Local-Var: a
- 12 Local-Var: i
- 12 Local-Var: a
- 12 Global-Var: norm
- 14 Local-Var: retv
- 14 Global-Var: pi*
- 14 Local-Var: a
- 14 Global-Var: norm
- 14 Arg-Var: b
- 15 Static-Var: stat
- 15 Static-Var: stat
- 16 Static-Var: stat
- 16 Static-Var: stat
- 16 Local-Var: retv
- 17 Local-Var: retv
- 17 Static-Var: stat
- 17 Static-Var: stat
-
- The function `x' is used to compute some arbitrary value. The
- list `stat' is used to keep track of how many times `x' is
- called, and to compute the average of the return
- value. fvscope shows us, line by line, each variable, and how
- it is bound.
-
- 3) Function arguments ------------------------------------------
-
- RLaB supports both "pass by reference" and "pass by value" for
- passing arguments to a function.
-
- Pass by reference means that the arguments, while still
- referred to be there declared names, are in fact bound to the
- caller's scope. Thus, the function can directly modify
- variables in the caller's scope.
-
- Pass by value means that a function cannot modify variables in
- the caller's scope - essentially, an argument that is passed
- by value is copied, and the copied value is passed to the
- function to operate on.
-
- Pass by reference can be considered the default behavior,
- since it takes no special effort on the user's part. Pass by
- value is achieved by declaring function arguments to be
- local. For example:
-
- // Pass by reference
-
- > myf = function ( A ) { A = "changed"; return A; }
- <user-function>
- > B=10;
- > myf(B);
- > B
- B =
- changed
-
- // Pass by value
- > myf = function ( A ) { local (A) A = "changed"; return A; }
- <user-function>
- > B=10;
- > myf(B);
- > B
- B =
- 10
-
- In the previous example B, a variable in the global workspace,
- is changed by myf (pass by reference). In the second part of
- the example, the function argument A, is redeclared to be
- local. This redeclaration forces the function argument to be
- passed by value.
-
- One advantage of this behavior is that users can create
- functions and selectively decide which variables should be
- passed by reference, and which should be passed by value.
-
- * * *
-
- You do not have to call a function with the same number of
- arguments specified in the definition. If you invoke a
- function with more arguments than declared, the result is an
- error. If you call the function with less arguments than
- declared, RLaB will pad the argument list with UNDEFINED,
- objects. Additionally, commas may be used to "